package com.anuo.app.study.StudyCollections;

import com.anuo.app.common.utils.IdUtil;
import com.anuo.app.common.utils.JsonUtil;
import com.anuo.app.common.utils.TestUtil;
import com.anuo.app.modules.study.entity.Product;
import com.anuo.app.modules.study.entity.User;
import com.google.common.collect.Sets;
import org.apache.commons.beanutils.BeanUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

import javax.naming.Name;
import javax.sound.midi.Soundbank;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = {"classpath:spring/spring-context.xml"})

/**
 java 集合(容器)
 笔记见有道 "Java 集合"
 @ 集合排序
 */
public class StudyCollections {



    /**
     * ArrayList 基本操作
     */
    @Test
    public void StudyArrayList() {
        //@create
        List<User> list = new ArrayList<>();
        User user = new User();
        user.setUsername("anuo");
        list.add(user);
        //@retrieve
        for (User item : list) {
            System.out.println(item.getUsername());
        }
        //获取第一个元素
        User user1 = list.get(0);
        //从集合中查出一个对象 见 findObjectInCollection 方法

        //@update
        //修改集合 见 updateCollection 方法
        //添加 list to list 用 addAll
        List<User> newList = new ArrayList<>();
        User user2 = new User();
        user2.setAddress("cd");
        newList.add(user2);
        list.addAll(newList);
        //@delete 见 updateCollection 方法
    }

    /**
     * Hashmap 常见操作
     */
    @Test
    public void StudyHashMap() {
        Map<String, String> map = new HashMap<>();
        //添加
        map.put("name", "anuo");
        map.put("sex", "男");
        //修改
        map.put("name", "anuo");
        map.put("name", "jk");
        System.out.println(map.get("name"));
        //删除
        map.remove("name");
        System.out.println(map.get("name"));

        //常见遍历,二次取值, 效率要低些
        for (String key : map.keySet()) {
            String value = map.get(key);
        }
        //高效遍历
        for (Map.Entry<String, String> entry : map.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
        }

        //java 8 更简单
        map.forEach((k,v)->{
            System.out.println("k:" + k + " v:" + v);
        });

        //检查是否有此key
        map.containsKey("anuo");
        //获取key
        System.out.println(map.get("name"));
    }

    /**
     * List 和数组Array 互转
     */
    @Test
    public void StudyArrayAndListConvert() {
        //array convert to list
        String[] array = {"jk", "anuo", "zs"};
        List<String> list = new ArrayList<>(Arrays.asList(array));
        list.add("ls");
        for (String s : list) {
            System.out.println("List value : " + s);
        }
        //list to array
        String[] array1 = new String[list.size()];
        list.toArray(array1);
        for (String s : array1) {
            System.out.println("Array value : " + s);
        }
    }


    /**
     * 数组 example
     */
    @Test
    public void studyArray() {
        //一般使用
        int[] intArray = new int[9];
        intArray[0] = 1;
        intArray[1] = 2;
        //声明就初始化
        int[] intArrayB = {1, 2, 3, 4};
        int[] intArrayC = new int[]{1, 2, 3, 4};
        System.out.println(intArrayC[2]);
        //注意一般不用 数组, 而是用集合(集合更灵活)如:
        List<Integer> listInt = new ArrayList<>();
        listInt.add(1);
        listInt.add(2);
        Integer i = listInt.get(0);
    }


    /**
     * 从集合中查出一个对象
     */
    @Test
    public void findObjectInCollection() {
        List<Product> productList = TestUtil.getProductList();
        //--原始查找
        List<Product> findList = new ArrayList<>();
        for (Product product : productList) {
            if ("cpu".equals(product.getName())) {
                findList.add(product);
            }
        }

        //--java 8 lambda 查找 list
        findList = productList.stream()
                .filter(e -> "cpu".equals(e.getName()))
                .collect(Collectors.toList());
        //--java 8 lambda 查找 一个
        Product product = productList.stream()
                .filter(e -> "cpu".equals(e.getName()))
                .findFirst()
                .orElse(null);

    }

    /**
     * 修改集合
     */
    @Test
    public void updateCollection() {
        //遍历集合时删除元素
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("jk");
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            String str = it.next();
            //遍历事删除元素
            if ("a".equals(str)) {
                it.remove();
            }

        }
        //遍历集合时增加元素
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).equals("jk")) {
                list.add("anuo");
            }
        }

        //输出
        for (String s : list) {
            System.out.println(s);
        }

        //修改 HashMap
        Map<String, String> map = new HashMap<>();
        map.put("name", "jk");
        map.put("name", "anon");//会修改name值

    }


    /**
     * 线程安全的集合
     */
    @Test
    public void studyCollectionThreadSafe() {
        //@线程安全的list
        //选择: google来看目前大多用  Collections.synchronizedList ,用 CopyOnWriteArrayList的也有
        //      用vector的很少
        //参考: https://stackoverflow.com/questions/9468187/collections-synchronizedlist-and-synchronized
        List<String> syncList = Collections.synchronizedList(new ArrayList<String>());
        syncList.add("jk");
        syncList.add("address");
        //注意: add 的时候不用 synchronized , 但是在遍历的时候一定要用synchronized, 原因见
        //ctrl+q 查看 Collections.synchronizedList 方法的文档. 如下:
        synchronized (syncList) {
            for (String s : syncList) {
                System.out.println(s);
            }
        }

        //@线程安全的 Set
        Set set = Sets.newConcurrentHashSet();//guava
        //@线程安全的 map
        //选择: ConcurrentHashMap 的性能比 HashTable的好
        Map<String, String> safeMap = new ConcurrentHashMap<>();
        safeMap.put("name", "jk");
        safeMap.put("age", "27");
        for (Map.Entry<String, String> item : safeMap.entrySet()) {
            System.out.println(item.getKey());
            System.out.println(item.getValue());
        }

    }

    /**
     * 创建一个不重复元素的集合
     */
    @Test
    public void studyNoDuplicate() {
        //有如下两种
        //1.用HashSet 搜索 eliminateDuplicateInHashSet 定位
        //2.在添加前判断元素是否存在,存在就不添加了
        List<Product> list = new ArrayList<>();
        Product product1 = new Product();
        product1.setName("jk");
        Product item = list.stream()
                .filter(e -> product1.getName().equals(e.getName()))
                .findFirst()
                .orElse(null);
        if (item == null) {
            list.add(product1);
        }
        System.out.println(JsonUtil.toJsonPretty(list));
    }

    /**
     * 集合排序
     * 参考: https://stackoverflow.com/questions/6957631/sort-java-collection
     */
    @Test
    public void studyCollectionSort() {
        //@java 8之前
        // 通过实现comparator接口来排序, 实例如下
        List<Product> productList = TestUtil.getProductList();

        Comparator<Product> comparator = new Comparator<Product>() {
            //按价格排序
            @Override
            public int compare(Product o1, Product o2) {
                //升序实例
                // 返回值 1表示大于, -1小于 , 0 等于
                if (o1.getPrice().compareTo(o2.getPrice()) == 1) {
                    return 1;
                } else if (o1.getPrice().compareTo(o2.getPrice()) == -1) {
                    return -1;
                }
                return 0;

                //region 降序实例
//                if (o1.getPrice().compareTo(o2.getPrice())==1) {
//                    return -1;
//                } else if (o1.getPrice().compareTo(o2.getPrice())==-1) {
//                    return 1;
//                }
//                return 0;

                //endregion 降序实例

            }
        };
        Collections.sort(productList, comparator);
        //System.out.println(JsonUtil.toJsonPretty(productList));

        //@java 8 写法 很简单
        List<Product> productListB = TestUtil.getProductList();
        //升序(按价格字段)
        productListB.sort(Comparator.comparing(Product::getPrice));
        //倒叙(按价格字段)
        productListB.sort(Comparator.comparing(Product::getPrice).reversed());

        System.out.println(JsonUtil.toJsonPretty(productListB));


    }

    @Test
    public void testMethod() {

    }
}


